package com.fjl.utils;

import com.alibaba.fastjson2.JSON;
import com.fjl.LogUtil;
import com.fjl.init.AbpmGlobalInfo;
import com.fjl.mapper.AbpmMapper;
import com.fjl.pojo.NextTaskDetail;
import com.fjl.pojo.StepInfoInAbxMultiBranch;
import com.fjl.pojo.po.AbpmRunTaskPO;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.mvel2.MVEL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class ParseBPMN {

    @Autowired
    private AbpmMapper abpmMapper;

    @Autowired
    IdGenerator idGenerator;

    /**
     * 获取当前节点下一个任务节点并刷新到结果集
     * @param flowNode 当前任务节点信息
     * @param currentTaskProcess 当前所在的流程图
     * @param variables 网关条件等，内容为json字符串
     * @param processInstanceId 流程唯一id
     * @param parentTaskId 父任务id
     * @param nextTaskDetail 结果集
     */
    public void nextTask(FlowNode flowNode, Process currentTaskProcess, String variables, String processInstanceId, String parentTaskId, NextTaskDetail nextTaskDetail) {
        LogUtil.info("nextTask_start");
        // 获取到下一个任务
        flowNode = nextElement(flowNode);
        if (flowNode instanceof UserTask) {
            refreshResultFromUserTask(flowNode, currentTaskProcess, nextTaskDetail);
        }
        if (flowNode instanceof ExclusiveGateway) {
            refreshResultFromExclusiveGateway(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
        }
        if (flowNode instanceof ParallelGateway) {
            // 并行分支
            if (flowNode.getOutgoingFlows().size()>1) {
                refreshResultFromParallelGateWay(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
            } else {
                // 并行汇聚
                if (refreshResultFromParallelGateWayMerge(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail))
                    return;
            }
        }
        if (flowNode instanceof CallActivity) {
            refreshResultFromCallActivity(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
        }

        if (flowNode instanceof EndEvent) {
            refreshResultFromEnd(flowNode, variables, processInstanceId, parentTaskId, nextTaskDetail);
        }
        LogUtil.info("nextTask_end");
    }

    /**
     * 结束节点后是否存在下一个任务，根据不同情况刷新到 nextTaskDetail 中
     * @param flowNode 当前任务节点
     * @param variables 网关条件等，内容为 json 字符串
     * @param processInstanceId 流程全局唯 一id
     * @param parentTaskId 当前流程父任务 id
     * @param nextTaskDetail 结果集
     */
    private void refreshResultFromEnd(FlowNode flowNode, String variables, String processInstanceId, String parentTaskId, NextTaskDetail nextTaskDetail) {
        Process currentTaskProcess;
        // 查询当前交易的全部任务
        List<AbpmRunTaskPO> currentTaskList = abpmMapper.selectRuTaskByProcessInstanceId(processInstanceId);
        // 当前任务对应callActivity任务
        List<AbpmRunTaskPO> task = currentTaskList.stream()
                .filter(abpmRunTaskPO -> parentTaskId.equals(abpmRunTaskPO.getId()))
                .collect(Collectors.toList());

        // 当前任务到达结束节点，判断是否有父流程
        // 存在父流程，提交父流程中的callActivity
        if (!task.isEmpty()) {
            // 获取并提交callActivity
            AbpmRunTaskPO taskPO = task.get(0);
            abpmMapper.deleteRuTaskById(taskPO.getId());
            // 定位当前callActivity所在流程图
            currentTaskProcess = AbpmGlobalInfo.processMap.get(taskPO.getProcDefId());
            // 定位当前任务所在流程图位置
            flowNode = (FlowNode) currentTaskProcess.getFlowElement(taskPO.getName());
            nextTaskDetail.setParentId(taskPO.getParentTaskId());
            nextTask(flowNode, currentTaskProcess, variables, processInstanceId, taskPO.getParentTaskId(), nextTaskDetail);

            //TODO 此时删除后 切换到下个callActiviti了  此时父id需要改变
//            nextTask(flowNode, currentTaskProcess, variables, processInstanceId, taskPO.getParentTaskId(), nextTaskDetail);
        }else {     // 不存在父流程，流程为结束节点
            if (flowNode.getName().equals("errorStop")){
                nextTaskDetail.setErrorStop(true);
                nextTaskDetail.setEnd(true);
            }else {
                nextTaskDetail.setEnd(true);
            }
        }
    }

    /**
     * callActivity节点的下一个任务，并刷新到 nextTaskDetail 中
     * @param flowNode 当前任务节点
     * @param currentTaskProcess 当前流程图
     * @param variables 网关条件等，内容为 json 字符串
     * @param processInstanceId 流程全局唯 一id
     * @param parentTaskId 当前流程父任务 id
     * @param nextTaskDetail 结果集
     */
    private void refreshResultFromCallActivity(FlowNode flowNode, Process currentTaskProcess, String variables, String processInstanceId, String parentTaskId, NextTaskDetail nextTaskDetail) {
        NextTaskDetail.TaskDetail taskDetail = nextTaskDetail.new TaskDetail();
        taskDetail.setProcDefId(currentTaskProcess.getId());
        taskDetail.setTask(flowNode);
        taskDetail.setCallActivityFlag(true);
        taskDetail.setSubProcessTaskDetail(new NextTaskDetail());
        nextTaskDetail.getTaskDetailList().add(taskDetail);
        currentTaskProcess = AbpmGlobalInfo.processMap.get(((CallActivity) flowNode).getCalledElement());
        FlowNode startEvent = currentTaskProcess.findFlowElementsOfType(StartEvent.class).get(0);
        nextTask(startEvent, currentTaskProcess, variables, processInstanceId, parentTaskId, taskDetail.getSubProcessTaskDetail());
    }

    /**
     * 并行网关汇聚节点的下一个任务，并刷新到 nextTaskDetail 中
     * @param flowNode 当前任务节点
     * @param currentTaskProcess 当前流程图
     * @param variables 网关条件等，内容为 json 字符串
     * @param processInstanceId 流程全局唯 一id
     * @param parentTaskId 当前流程父任务 id
     * @param nextTaskDetail 结果集
     * @return 是否还有其他并行任务未完成
     */
    private boolean refreshResultFromParallelGateWayMerge(FlowNode flowNode, Process currentTaskProcess, String variables, String processInstanceId, String parentTaskId, NextTaskDetail nextTaskDetail) {
        List<AbpmRunTaskPO> currentTaskList = abpmMapper.selectRuTaskByProcessInstanceId(processInstanceId);
        // 获取当前流程图中存在的待执行任务
        List<AbpmRunTaskPO> isParallelGateway = currentTaskList.stream()
                .filter(abpmRunTaskPO -> null == abpmRunTaskPO.getParentTaskId() || "".equals(abpmRunTaskPO.getParentTaskId()))
                .collect(Collectors.toList());
        // 获取并行网关中全部的任务
        ArrayList<Activity> tasksFromParallelGateway = new ArrayList<>();
        collectTasksFromParallelGateway(flowNode, tasksFromParallelGateway);
        for (Activity userTask : tasksFromParallelGateway) {
            // 待执行任务在并行网关内，停止进行推行
//            if (isParallelGateway.stream()
            if (currentTaskList.stream()
                    .anyMatch(abpmRunTaskPO -> userTask.getId().equals(abpmRunTaskPO.getName()))) {
                return true;
            }
        }
        // 待执行任务不在并行网关中，继续推行
        nextTask(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
        return false;
    }

    /**
     * 获取并行网关区间内的任务
     * @param flowNode 当前并行网关节点
     * @param tasksFromParallelGateway  并行网关区间内任务节点
     */
    private void collectTasksFromParallelGateway(FlowNode flowNode, List<Activity> tasksFromParallelGateway) {
        for (SequenceFlow incomingFlow : flowNode.getIncomingFlows()) {
            FlowElement task = incomingFlow.getSourceFlowElement();
            if (task instanceof UserTask || task instanceof CallActivity) {
                tasksFromParallelGateway.add((Activity) task);
                for (SequenceFlow flow : ((Activity) task).getIncomingFlows()) {
                    if (!(flow.getSourceFlowElement() instanceof ParallelGateway)) {
                        collectTasksFromParallelGateway((FlowNode) task, tasksFromParallelGateway);
                    }
                }
            }
        }
    }

    /**
     * 排他节点的下一个任务，并刷新到 nextTaskDetail 中
     * @param flowNode 当前任务节点
     * @param currentTaskProcess 当前流程图
     * @param variables 网关条件等，内容为 json 字符串
     * @param processInstanceId 流程全局唯 一id
     * @param parentTaskId 当前流程父任务 id
     * @param nextTaskDetail 结果集
     */
    private void refreshResultFromExclusiveGateway(FlowNode flowNode, Process currentTaskProcess,  String variables, String processInstanceId, String parentTaskId, NextTaskDetail nextTaskDetail) {
        for (SequenceFlow outgoingFlow : flowNode.getOutgoingFlows()) {
            if (evaluateCondition(outgoingFlow.getConditionExpression(), variables)) {
                flowNode = (FlowNode) outgoingFlow.getTargetFlowElement();
                // 排他网关后接 userTask 任务
                if (flowNode instanceof UserTask) {
                    refreshResultFromUserTask(flowNode, currentTaskProcess, nextTaskDetail);
                }
                // 排他网关后接排他网关
                if (flowNode instanceof ExclusiveGateway) {
                    refreshResultFromExclusiveGateway(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
                }
                // 排他网关后接并行网关
                if (flowNode instanceof ParallelGateway) {
                    // 并行分支
                    if (flowNode.getOutgoingFlows().size()>1) {
                        refreshResultFromParallelGateWay(flowNode, currentTaskProcess,  variables, processInstanceId, parentTaskId, nextTaskDetail);
                    } else {
                        // 并行汇聚
                        if (refreshResultFromParallelGateWayMerge(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail))
                            return;
                    }
                }
                // 排他网关后接 CallActivity
                if (flowNode instanceof CallActivity) {
                    refreshResultFromCallActivity(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
                }

                if (flowNode instanceof EndEvent) {
                    refreshResultFromEnd(flowNode, variables, processInstanceId, parentTaskId, nextTaskDetail);
                }
            }
        }
    }

    /**
     * 并行网关开启后刷新到结果集
     * @param flowNode 当前任务
     * @param currentTaskProcess 当前流程
     * @param variables 网关条件等，内容为json字符串
     * @param processInstanceId 流程全局唯一id
     * @param parentTaskId 该任务父任务id
     * @param nextTaskDetail 结果集
     */
    private void refreshResultFromParallelGateWay(FlowNode flowNode, Process currentTaskProcess, String variables, String processInstanceId, String parentTaskId, NextTaskDetail nextTaskDetail) {
        List<SequenceFlow> flowList = flowNode.getOutgoingFlows();
        for (SequenceFlow outgoingFlow : flowList) {
            flowNode = (FlowNode) outgoingFlow.getTargetFlowElement();
            // 并行网关后接 userTask 任务
            if (flowNode instanceof UserTask) {
                refreshResultFromUserTask(flowNode, currentTaskProcess, nextTaskDetail);
            }
            // 并行网关后接排他网关
            if (flowNode instanceof ExclusiveGateway) {
                refreshResultFromExclusiveGateway(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
            }
            // 并行网关后接并行网关
            if (flowNode instanceof ParallelGateway) {
                // 并行分支
                if (flowNode.getOutgoingFlows().size()>1) {
                    refreshResultFromParallelGateWay(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
                } else {
                    // 并行汇聚
                    if (refreshResultFromParallelGateWayMerge(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail))
                        return;
                }
            }
            // 并行网关后接 CallActivity
            if (flowNode instanceof CallActivity) {
                refreshResultFromCallActivity(flowNode, currentTaskProcess, variables, processInstanceId, parentTaskId, nextTaskDetail);
            }
        }
    }

    /**
     * UserTask刷新到结果集
     * @param flowNode 当前任务
     * @param currentTaskProcess 当前流程
     * @param nextTaskDetail 结果集
     */
    private static void refreshResultFromUserTask(FlowNode flowNode, Process currentTaskProcess, NextTaskDetail nextTaskDetail) {
        NextTaskDetail.TaskDetail taskDetail = nextTaskDetail.new TaskDetail();
        taskDetail.setProcDefId(currentTaskProcess.getId());
        taskDetail.setProcessVersion(currentTaskProcess.getDocumentation());
        taskDetail.setCallActivityFlag(false);
        taskDetail.setTask(flowNode);
        nextTaskDetail.getTaskDetailList().add(taskDetail);
    }

    /**
     * 计算网关条件与提供数据是否通过
     * @param conditionExpression 网关表达式
     * @param variables 提供网关所需数据
     * @return 通过返回true，否则返回false
     */
    private boolean evaluateCondition(String conditionExpression, String variables) {
        Map map = JSON.parseObject(variables, Map.class);
        if (conditionExpression == null || conditionExpression.trim().isEmpty()) {
            return true;
        }
        if (map == null) {
            return false;
        }
        try {
            return MVEL.evalToBoolean(conditionExpression.replaceAll("[\\$\\{\\}]", ""), map);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 当下一个节点为单条连线时获取下一个节点
     * @param flowNode 当前节点
     * @return 返回下一个节点
     */
    private FlowNode nextElement(FlowNode flowNode) {
        SequenceFlow sequenceFlow = flowNode.getOutgoingFlows().get(0);
        return (FlowNode) sequenceFlow.getTargetFlowElement();
    }

    /**
     * 创建任务
     * @param id 任务id
     * @param name 任务key
     * @param procDefId 流程图定义id
     * @param executionId 执行器id
     * @param processInstanceId 流程实例唯一id
     * @param parentTaskId 该任务富任务id
     * @param moduleName 模块名称
     * @return  taskId：任务id，taskKey：任务key，procDefId：流程图定义id,executionId:执行器id,processInstanceId:流程实例唯一id
     */
    public AbpmRunTaskPO createTask(String id, String name, String procDefId, String executionId, String processInstanceId, String parentTaskId, String moduleName, String rootProcessId) {
        LogUtil.info("createTask_start");
        id = generateValue(id);
        executionId = generateValue(executionId);
        processInstanceId = generateValue(processInstanceId);
        LocalDateTime currentDateTime = LocalDateTime.now();
        AbpmRunTaskPO abpmRunTaskPO = new AbpmRunTaskPO(id, name, procDefId, executionId, currentDateTime, processInstanceId, parentTaskId, moduleName, rootProcessId);
        LogUtil.info("createTask_start-开始入库");
        long l = System.currentTimeMillis();
        abpmMapper.insertRuTask(abpmRunTaskPO);
        l = System.currentTimeMillis()-l;
        LogUtil.error("createTask_start-入库结束,time="+l+"ms");
        return abpmRunTaskPO;
    }

    /**
     * 根据传参判断是否通过雪花算法生成唯一id
     * @param value 当前传参
     * @return 当前传参不为null直接返回传参，否者生成唯一id
     */
    private String generateValue(String value) {
        return value != null ? value : String.valueOf(idGenerator.nextID());
    }

//    public List<Map<String, Object>> pathInfoList(Process process, String variables) {
//        ArrayList<Map<String, Object>> pathInfoList = new ArrayList<>();
//        FlowNode flowNode = process.findFlowElementsOfType(StartEvent.class).get(0);
//        while (flowNode.getOutgoingFlows() != null) {
//            if (flowNode instanceof  StartEvent) {
//                flowNode = (FlowNode) flowNode.getOutgoingFlows().get(0).getTargetFlowElement();
//            }
//            if (flowNode instanceof EndEvent) {
//                break;
//            }
//            if (flowNode instanceof UserTask || flowNode instanceof CallActivity) {
//                HashMap<String, Object> map = new HashMap<>();
//                String name = flowNode.getName();
//                map.put("pathTaskName", name);
//                String id = flowNode.getId();
//                map.put("pathTaskKey", id);
//                if (flowNode.getAttributes().containsKey("virtual")) {
//                    String virtual = flowNode.getAttributes().get("virtual").get(0).getValue();
//                    map.put("virtual", virtual);
//                }else {
//                    map.put("virtual", true);
//                }
//                pathInfoList.add(map);
//            }
//            boolean flag = true;
//            if (flowNode instanceof ExclusiveGateway) {
//                for (SequenceFlow outgoingFlow : flowNode.getOutgoingFlows()) {
//                    if (evaluateCondition(outgoingFlow.getConditionExpression(), variables)) {
//                        flowNode = (FlowNode) outgoingFlow.getTargetFlowElement();
//                        flag = false;
//                    }
//                }
//            }
//            if (flag) {
//                flowNode = (FlowNode) flowNode.getOutgoingFlows().get(0).getTargetFlowElement();
//            }
//
//        }
//        return pathInfoList;
//    }

    public List<StepInfoInAbxMultiBranch> futureStepInfoList(Process process, String variables) {
        ArrayList<StepInfoInAbxMultiBranch> futureStepInfoList = new ArrayList<>();
        FlowNode flowNode = process.findFlowElementsOfType(StartEvent.class).get(0);
        while (flowNode.getOutgoingFlows() != null) {
            if (flowNode instanceof  StartEvent) {
                flowNode = (FlowNode) flowNode.getOutgoingFlows().get(0).getTargetFlowElement();
            }
            if (flowNode instanceof EndEvent) {
                futureStepInfoList.forEach(stepInfo -> stepInfo.setEndStepFlag(true));
                break;
            }
            if (flowNode instanceof UserTask) {
                StepInfoInAbxMultiBranch futureStepInfo = new StepInfoInAbxMultiBranch();
                String name = flowNode.getName();
                futureStepInfo.setStepName(name);
                String id = flowNode.getId();
                futureStepInfo.setStepKey(id);
                UserTask flowNode1 = (UserTask) flowNode;
                for (FormProperty formProperty : flowNode1.getFormProperties()) {
                    if (formProperty.getId().equals("重复提交标志") ) {
                        futureStepInfo.setRepeatedCommitFlag(formProperty.getDefaultExpression());
                    }
                    if (formProperty.getId().equals("调用服务标识") ) {
                        futureStepInfo.setServiceFlag(formProperty.getDefaultExpression());
                    }
                    if (formProperty.getId().equals("调用服务码") ) {
                        futureStepInfo.setServiceCode(formProperty.getDefaultExpression());
                    }
                    if (formProperty.getId().equals("version") ) {
                        futureStepInfo.setUserTaskVersion(formProperty.getDefaultExpression());
                    }
                }
                futureStepInfo.setProcessVersion(process.getDocumentation());

                futureStepInfoList.add(futureStepInfo);
            }
            if (flowNode instanceof ExclusiveGateway) {
                for (SequenceFlow outgoingFlow : flowNode.getOutgoingFlows()) {
                    if (evaluateCondition(outgoingFlow.getConditionExpression(), variables)) {
                        flowNode = (FlowNode) outgoingFlow.getTargetFlowElement();
                    }
                }
            }
                flowNode = (FlowNode) flowNode.getOutgoingFlows().get(0).getTargetFlowElement();
            }

        return futureStepInfoList;
    }

//    /**
//     * 根据提供的 id 通过优先级获取到对应流程图,查找优先级为 当前交易下的静态子流程 > 当前交易下的动态子流程 > 当前工程下的静态子流程 > 当前工程下的动态子流程
//     * 案例如下:
//     * 动态流程配置文件为:
//     * {
//     *   "variables": {
//     *     "openTradeType": "dm:openTradeType"
//     *   },
//     *   "keyExpression": "openTradeType",
//     *   "mapping": {
//     *     "1-1-0": "sskk",
//     *     "1-2-0": "ssfk",
//     *     "1-3-0": "xkkk",
//     *     "1-4-0": "klpzk",
//     *     "1-5-0": "hqybt",
//     *     "1-6-0": "zxhq",
//     *     "1-7-0": "kxhq",
//     *     "2-0-1": "zczq",
//     *     "2-0-2": "decd_xyc",
//     *     "2-0-3": "decd_xyc",
//     *     "2-0-4": "tzck",
//     *     "2-0-5": "dhlb",
//     *     "2-0-6": "lczq",
//     *     "2-0-7": "dqybt"
//     *   }
//     * }
//     * 调用方法时参数为:
//     * getCallActivityProcess(scene/trade/TE/ckyw/dsyw/t01001, openAcct, {'openTradeType':'1-1-0'}, BankModule)
//     * 交易与工程子流程在流程定义上主要区别为:
//     * 交易子流程在一级流程中的id为单独的信息,比如openAcct,对应二级流程id却是scene/trade/TE/ckyw/dsyw/t01001/openAcct
//     * 工程子流程在一级流程中的id为完整的信息,比如scene/trade/TE/ckyw/dsyw/t01001/openAcct,对应的二级流程id与之一一对应
//     * @param currentProDefId 当前 callActivity 所在流程图的ID
//     * @param callActivityId 当前 callActivity 的 ID
//     * @param variablesJson 请求写的的变量,内部可能包含动态子流程所需内容
//     * @return 当前 callActivity 的流程图
//     */
//    public Process getProcess(String currentProDefId, String callActivityId, String variablesJson, String moduleName){
//        // 流程定义 proDefId
//        String proDefId;
//        // callActivity 对应流程图
//        Process process;
//        // 动态子流程文件映射的 Key
//        String dynamicSubProcessKey;
//        // 1.先从当前交易下的静态子流程寻找
//        proDefId = moduleName + ":" + currentProDefId + "/" + callActivityId;
//        process = AbpmGlobalInfo.processMap.get(proDefId);
//        // 2.未获取到再次从当前交易下的动态子流程获取
//        if (process == null) {
//            // 2.1 获取当前交易下是否存在配置的动态子流程信息
//            JSONObject jsonObject = AbpmGlobalInfo.indexJsonConfig.get("fjl-abpm/process/" + moduleName +":" + currentProDefId + "/" +  callActivityId);
//            if (jsonObject != null) {
//                // 2.2 获取动态子流程所需的前端传递的 key 值
//                String keyExpression = (String) jsonObject.get("keyExpression");
//                // 2.3 解析前端传递的 JSON 字符串
//                JSONObject jsonObjectFromFront = JSON.parseObject(variablesJson);
//                // 2.4 判断是否传递动态子流程需要的参数
//                if (jsonObjectFromFront.containsKey(keyExpression)){
//                    // 2.5 获取到需要执行动态子流程的 key
//                    dynamicSubProcessKey = (String) jsonObjectFromFront.get(keyExpression);
//                    // 2.6 从动态子流程配置文件中获取到子流程映射 map
//                    Map<String, String> dynamicSubProcessMap = (Map<String, String>) jsonObject.get("mapping");
//                    // 2.7 获取到动态子流程简易id
//                    String dynamicSubProcessValue = dynamicSubProcessMap.get(dynamicSubProcessKey);
//                    proDefId = moduleName + ":" + currentProDefId + "/" + dynamicSubProcessValue;
//                    process = AbpmGlobalInfo.processMap.get(proDefId);
//                }
//            }
//        }
//        // 3. 未获取到再次从当前工程下的静态子流程寻找
//        if (process == null) {
//            proDefId = moduleName + ":" + callActivityId;
//            process = AbpmGlobalInfo.processMap.get(proDefId);
//        }
//        // 4. 未获取到再次从当前工程下的动态子流程寻找
//        if (process == null) {
//            // 2.1 获取当前交易下是否存在配置的动态子流程信息
//            JSONObject jsonObject = AbpmGlobalInfo.indexJsonConfig.get("process/" + moduleName + ":" +  callActivityId);
//            if (jsonObject != null) {
//                // 2.2 获取动态子流程所需的前端传递的 key 值
//                String keyExpression = (String) jsonObject.get("keyExpression");
//                // 2.3 解析前端传递的 JSON 字符串
//                JSONObject jsonObjectFromFront = JSON.parseObject(variablesJson);
//                // 2.4 判断是否传递动态子流程需要的参数
//                if (jsonObjectFromFront.containsKey(keyExpression)){
//                    // 2.5 获取到需要执行动态子流程的 key
//                    dynamicSubProcessKey = (String) jsonObjectFromFront.get(keyExpression);
//                    // 2.6 从动态子流程配置文件中获取到子流程映射 map
//                    Map<String, String> dynamicSubProcessMap = (Map<String, String>) jsonObject.get("mapping");
//                    // 2.7 获取到动态子流程简易id
//                    String dynamicSubProcessValue = dynamicSubProcessMap.get(dynamicSubProcessKey);
//                    proDefId = moduleName + ":" + dynamicSubProcessValue;
//                    process = AbpmGlobalInfo.processMap.get(proDefId);
//                }
//            }
//        }
//        return process;
//    }
}
